import fs from 'fs';
import path from 'path';
import { Interface } from 'yapi-to-typescript';

import { camelCase, lowerCase, map, replace, split, upperFirst, trimEnd, groupBy, forEach, trim, trimStart, isNil, isEmpty, forIn, includes, findIndex } from 'lodash';
import { getRequestName, getResponseName, underlineToHump } from './name';
import { config } from '../config';

export interface IParameters {
  sign: string;
  catid: number;
  path: string;
  shortpath: string;
  interfaceInfo: Interface;
  up_time: number;
}
export const generateShortPath = (path: string) => {
  const pathArr = split(trim(path, '/'), '/');
  if (pathArr.length >= 2) {
    pathArr.pop();
    return pathArr.join('/');
  }
  return 'common';
};
/**
 * 处理配置接口基本路径情况
 * @param interfaceInfo
 */
export const handleBaseRootPath = (interfaceInfo: Interface): string => {
  const { basepath } = interfaceInfo._project; //url 根节点
  let path = interfaceInfo.path;
  if (basepath && basepath != '/') {
    path = replace(path, basepath, '');
  }
  return path;
};
export const parseParamsPath = (interfaceInfo: Interface): string => {
  let path = handleBaseRootPath(interfaceInfo);
  if (interfaceInfo.req_params.length > 0) {
    const params = map(interfaceInfo.req_params, (item: any) => {
      return '/{' + item.name + '}';
    });
    map(params, (item: any) => {
      path = replace(path, item, '');
    });
  }
  return path;
};
/**
 * 生成Api接口名称
 * @param interfaceInfo : Interface
 * @param changeCase:ChangeCase
 * @returns
 */
export const genApiInterfaceName = (interfaceInfo: Interface, isShowExt = true, ext = 'request') => {
  let lastPath = '';
  let arr: Array<string> = [];
  let name = '';
  const path = parseParamsPath(interfaceInfo);
  arr = split(path, '/');
  if (arr.length > 2) {
    name = arr[arr.length - 1];
    lastPath = arr[arr.length - 2];
  } else {
    name = arr[arr.length - 1];
    lastPath = '';
  }

  // 拼接前缀路径+文件名称
  if (isShowExt) {
    if (lastPath != '') {
      return upperFirst(camelCase(lastPath + '-' + name + '-' + ext));
    } else {
      return upperFirst(camelCase(name + '-' + ext));
    }
  } else {
    if (lastPath != '') {
      return upperFirst(camelCase(lastPath + '-' + name));
    } else {
      return upperFirst(camelCase(name));
    }
  }
};

export const generateApi = (apiMaps: Array<IParameters>) => {
  const apiTemplate = fs.readFileSync(path.join(__dirname, '../templates/apiTemplate/api.tpl')).toString();
  const pkg: Array<{ methodName: string; url: string }> = [];
  map(apiMaps, (api: IParameters) => {
    if (api.interfaceInfo.req_body_form.length > 0 || api.interfaceInfo.req_query.length > 0 || (api.interfaceInfo.req_body_other && api.interfaceInfo.req_body_other.length > 0))
      pkg.push({
        methodName: getRequestName(api.interfaceInfo),
        url: replace(config.typepath, config.searchPath, '/@/') + trimStart(underlineToHump(api.path), '/'),
      });
    if (!isNil(api.interfaceInfo['res_body_type']) && api.interfaceInfo.res_body_type == 'json') {
      const resbody = JSON.parse(api.interfaceInfo.res_body);

      if (!isNil(resbody['type']) && resbody['type'] == 'object') {
        if (!isNil(resbody['properties']['result']['properties']) && !isEmpty(resbody['properties']['result']['properties'])) {
          pkg.push({
            methodName: getResponseName(api.interfaceInfo),
            url: replace(config.typepath, config.searchPath, '/@/') + trimStart(underlineToHump(api.path), '/'),
          });
        }

        if (!isNil(resbody['properties']['result']['items'])) {
          pkg.push({
            methodName: getResponseName(api.interfaceInfo),
            url: replace(config.typepath, config.searchPath, '/@/') + trimStart(underlineToHump(api.path), '/'),
          });
        }
      }
    }
  });
  const arr = groupBy(pkg, 'url');
  let packageStr = '';
  map(arr, (items: Array<{ methodName: string; url: string }>, inx: string) => {
    const module = items.map((item) => item.methodName).join(',');
    packageStr += `import { ${module} } from '${inx}';\r\n`;
  });
  return apiTemplate.replace('{Wrapper}', packageStr);
};

export const generateApiFunction = (api: Interface) => {
  const apiBodyTemplate = fs.readFileSync(path.join(__dirname, '../templates/apiTemplate/body.tpl')).toString();

  // 是否需要body
  const isNeedBody = ['post', 'put'].includes(api.method.toLocaleLowerCase());
  // 接口描述
  const description = api.title;
  let methodName = '';

  if (api.req_query.length > 0) {
    methodName = 'Query';
  }
  if (api.req_params.length > 0) {
    methodName = 'Path';
  }
  if (api.path == '/system/auxiliary/brand/checkCodeUnique') {
    //console.log(api);
  }
  const tmpFunName = genApiInterfaceName(api, false);
  let funName = '';
  // 接口名字
  if (lowerCase(tmpFunName).indexOf('get') != -1 || lowerCase(tmpFunName).indexOf('post') != -1) {
    funName = genApiInterfaceName(api, false);
  } else {
    funName = upperFirst(lowerCase(api.method)) + genApiInterfaceName(api, false);
  }
  const interfaceName = `api${funName}${methodName}`;
  // URL参数
  let urlParams = `${getUrlQuery(api.req_params)}`;

  let isurljoin = false;
  // 参数Query
  let queryParam = api.req_query.length > 0 ? `params: ${getRequestName(api)},` : '';
  if (api.req_query.length == 1) {
    if (api.req_query[0].name != 'query') {
      isurljoin = true;
    }
  }
  // 请求方法
  let method = api.method.toLocaleLowerCase();
  // 请求URL
  const url = api.path.replace(/{(.*?)}/g, '${$1}');
  let bodyParam = '';
  if (api.req_body_type == 'form' && method == 'post') {
    method = 'postForm';
    if (isNeedBody) {
      if (api.req_body_form && api.req_body_form.length > 0) {
        bodyParam = `params: ${getRequestName(api)},`;
      }
    }
  }
  if (api.req_body_type == 'raw' && method == 'post') {
    method = 'post';
    if (isNeedBody) {
      if (api.req_body_form && api.req_body_form.length > 0) {
        bodyParam = `params: ${getRequestName(api)},`;
      }
      if (api.req_query.length > 0 && !isurljoin) {
        method = 'postForm';
      }
    }
  }
  // if (api.path == '/system/auxiliary/category/list') {
  //   console.log(api);
  // }
  if (isNeedBody && api.req_body_other && api.req_body_other.length > 0) {
    bodyParam = `params: ${getRequestName(api)},`;
  }
  // if (isNeedBody && api.req_body_other && api.req_body_other.length > 0 && api.req_query.length > 0 && !isurljoin) {
  //   queryParam = '';
  //   bodyParam = `params: ${getRequestName(api)},`;
  // }
  let params = '';
  if (queryParam || bodyParam) {
    params = ',params';
    queryParam = trimEnd(queryParam, ',');
    bodyParam = trimEnd(bodyParam, ',');
  } else {
    urlParams = trimEnd(urlParams, ',');
  }
  let response = '';

  //返回值约束类型
  if (!isNil(api.res_body_type) && api.res_body_type == 'json') {
    const resbody = JSON.parse(api.res_body);

    if (!isNil(resbody['type']) && resbody['type'] == 'object') {
      if (
        !isNil(resbody['properties']['result']['type']) &&
        resbody['properties']['result']['type'] == 'object' &&
        !isNil(resbody['properties']['result']['properties']) &&
        !isEmpty(resbody['properties']['result']['properties'])
      ) {
        response = getResponseName(api);
      }

      if (!isNil(resbody['properties']['result']['type']) && resbody['properties']['result']['type'] == 'array') {
        response = getResponseName(api);
      }
    }
  }

  const bodyContent = apiBodyTemplate
    .replace('{Description}', description)
    .replace('{InterfaceName}', interfaceName)
    .replace('{UrlParams}', urlParams)
    .replace('{QueryParams}', queryParam)
    .replace('{queryParamConfig}', !isEmpty(queryParam) && isurljoin ? ',{joinParamsToUrl:true}' : '')
    .replace('{BodyParams}', bodyParam)
    .replace('{Method}', method)
    .replace('{Url}', url)
    .replace('{ResponseBody}', isEmpty(response) ? '' : `<${response}>`)
    .replace('{params}', params);
  return bodyContent;
};

export const generateColumnSchemaFunction = (api: Interface): string => {
  const apiBodyTemplate = fs.readFileSync(path.join(__dirname, '../templates/dataTemplate/column.tpl')).toString();
  const apiSchemaTemplate = fs.readFileSync(path.join(__dirname, '../templates/dataTemplate/schema.tpl')).toString();
  const columnList = config.columnList;

  const columns: Array<string> = [];
  const formList: Array<string> = [];

  for (let i = 0; i < columnList.length; i++) {
    if (api.path.indexOf(columnList[i]) !== -1) {
      //strlist = columnList[i];

      //生成列
      const { result } = JSON.parse(api.res_body)['properties'];

      let arr = [];
      if (result.type == 'object') {
        arr = result?.properties?.rows?.items?.properties ?? [];
      } else if (result.type == 'array') {
        arr = result?.items?.properties ?? [];
      }

      forEach(arr, (item: any, inx: string) => {
        columns.push(`{title:"${item?.description ?? ''}", dataIndex:"${inx}"}`);
      });

      if (api.req_query.length > 0) {
        api.req_query.forEach((query) => {
          formList.push(`{field: '${query.name}',label: '${query.desc ?? ''}',component: 'Input'}`);
        });
      }
      // if (api.path == '/system/basic/custom/list') {
      //   console.log(api);
      // }
      //表单搜索
      if (!isNil(api.req_body_other)) {
        const { properties } = JSON.parse(api.req_body_other);
        forIn(properties, (item: any, inx: string) => {
          if (!includes(config.searchForm, inx)) {
            formList.push(`{field: '${inx}',label: '${item.description ?? ''}',component: 'Input'}`);
          }
        });
      }

      break;
    }
  }

  //生成表单数据
  const schemaList = config.schemaForm;
  const schemaFormList: Array<string> = [];
  for (let i = 0; i < schemaList.length; i++) {
    if (api.path.indexOf(schemaList[i]) !== -1 && (api.method == 'POST' || api.method == 'PUT')) {
      //strform = schemaList[i];

      const pathName = trimEnd(replace(api.path, /{(.*?)}/g, ''), '/');
      //@ts-ignore
      if (!global.globalMap.has(pathName)) {
        //@ts-ignore
        global.globalMap.set(pathName, true);
        if (!isNil(api.req_body_other)) {
          const { properties } = JSON.parse(api.req_body_other);

          forEach(properties, (item: any, inx: string) => {
            schemaFormList.push(`{field: '${inx}',label: '${item.description ?? ''}',component: 'Input'}`);
          });
        }
      }

      break;
    }
  }
  let columnStr = '';
  if (columns.length > 0) {
    columnStr = apiBodyTemplate.replace('{columnName}', 'use' + genApiInterfaceName(api, true, 'Columns')).replace('{columns}', columns.join(',\r\n')) + '\r\n';
  }
  let schemaStr = '';
  //表单搜索条件
  if (formList.length > 0) {
    schemaStr = apiSchemaTemplate.replace('{schemaName}', 'use' + genApiInterfaceName(api, true, 'SearchForm')).replace('{schemas}', formList.join(',\r\n')) + '\r\n';
  }
  let schemaFormStr = '';
  if (schemaFormList.length > 0) {
    schemaFormStr = apiSchemaTemplate.replace('{schemaName}', 'use' + genApiInterfaceName(api, true, 'SchemaForm')).replace('{schemas}', schemaFormList.join(',\r\n')) + '\r\n';
  }
  return columnStr + schemaStr + schemaFormStr;
};
// 获取路径参数
const getUrlQuery = (params: any[]) => {
  return params && params.length > 0 ? params.map((e) => `${e.name}: string|number`).join(',') + ',' : '';
};
